#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "funciones.h"
#include "Configuracion.h"

#define BACKLOG 10     // Conecciones pendientes permitidas
#define BUFFER_SIZE 1024

int main(void)
{
    int sockfd, new_fd;  // listen en sock_fd, new connection en new_fd
    struct sockaddr_in my_addr;    // my address information
    struct sockaddr_in their_addr; // connector's address information
    int sin_size, i, myPort;
	long fileSize, sentBytes;
	char filename[255], fullFileName[BUFFER_SIZE];
	char buffer[BUFFER_SIZE], http[9], buffo[BUFFER_SIZE], message[BUFFER_SIZE];
	FILE *fileToOpen;

	myPort=atoi(LeerArchivoConfiguracion("PUERTO",1));
	
    sockfd = socket(PF_INET, SOCK_STREAM, 0);
	if (sockfd == -1) 
	{
		perror("socket()");
		exit(EXIT_FAILURE);
	}

    my_addr.sin_family = AF_INET;         // host byte order
	
    my_addr.sin_port = htons(myPort);     // short, network byte order
    my_addr.sin_addr.s_addr = INADDR_ANY; // auto-fill with my IP
    memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);
    
    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr)==-1)
	{ 
		perror("bind()");  
		exit(EXIT_FAILURE);
	}
	
    if (listen(sockfd, BACKLOG)==-1)
	{
		perror("listen()");
		exit(EXIT_FAILURE);
	}

	/* Bucle principal de recepcion y envio de paquetes */
	while (1) 
	{
		/* Limpieza del buffer */
		memset (buffer, '\0', BUFFER_SIZE);

		sin_size = sizeof their_addr;
		new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
		
		if (new_fd == -1) 
		{ 
			perror("accept()");  
			exit(EXIT_FAILURE);
		}
	
		/* Recibimos datos */
		if (recv(new_fd,buffer,sizeof(buffer),0)==-1) 
		{
			perror("recv()");  
			exit(EXIT_FAILURE);
		}

		ParseMessage(buffer, filename, http);
	
		strcpy(fullFileName, LeerArchivoConfiguracion("DIR",1));
		strcat(fullFileName, filename);
		if (FileExists(fullFileName)){
			HttpResponse(message, http, filename, 1);
			if (send(new_fd, message, strlen(message),0) == -1) 
			{ 
				perror("send()");  
				exit(EXIT_FAILURE);
			}

			fileToOpen = fopen(fullFileName,"rb");
			fileSize = GetFileSize(fileToOpen);

			for(i=0; i<fileSize/BUFFER_SIZE; i++)
			{
				fread(buffo, BUFFER_SIZE, 1, fileToOpen);
				sentBytes = send(new_fd, buffo, BUFFER_SIZE, 0);
			
				if (sentBytes == -1) 
				{
					perror("send()");  
					exit(EXIT_FAILURE);
				}
				if (sentBytes != BUFFER_SIZE)
				{ 
					perror("send() - Envio de menos");  
					exit(EXIT_FAILURE);
				}
			}
			fread(buffo, fileSize%BUFFER_SIZE, 1, fileToOpen);
			sentBytes = send(new_fd, buffo, fileSize%BUFFER_SIZE, 0);
		
			if (sentBytes == -1) 
			{
				perror("send()");  
				exit(EXIT_FAILURE);
			}	
			if (sentBytes != fileSize%BUFFER_SIZE)
			{ 
				perror("send() - Envio de menos");  
				exit(EXIT_FAILURE);
			}
			
		}else{
			HttpResponse(message, http, filename, 0);
			if (send(new_fd, message, strlen(message),0) == -1) 
			{ 
				perror("send()");  
				exit(EXIT_FAILURE);
			}
		}
		memset(buffer, '\0', BUFFER_SIZE);
		memset(buffo, '\0', BUFFER_SIZE);
		memset(message, '\0', BUFFER_SIZE);
		memset(filename, '\0', 255);
		memset(http, '\0', 8);
		/* Cierre del descriptor de archivo */
		close(new_fd);
	}		
 }
